package up7.model;
import up7.biz.FolderSchema;
import up7.sql.DataBaseAttribute;
import up7.utils.PathTool;
import up7.utils.UtilsTool;

import java.io.File;
import java.util.Date;

/*
 * 原型
 * 更新记录：
 * 	2016-01-07
 * 		FileMD5更名为md5
 * 		PostComplete更名为complete
 * 		FileLength更名为lenLoc
 * 		FileSize更名为sizeLoc
 * 		PostedPercent更名为perSvr
*/
public class FileInf {

	public enum StorageType {
		IO,FastDFS,Minio,OSS,OBS;
	}
	
	public static FileInf build(){return  new FileInf();}

	public FileInf()
	{
	}

	@DataBaseAttribute(name="f_id")
	public String id="";
	public String getid(){return this.id;}

	@DataBaseAttribute(name="f_pid")
	public String pid="";
	public String getpid(){return this.pid;}

	@DataBaseAttribute(name="f_pidRoot")
	public String pidRoot="";
	public String getpidRoot(){return this.pidRoot;}

	/**  * 表示当前项是否是一个文件夹项。	*/
	@DataBaseAttribute(name="f_fdTask")
	public boolean fdTask=false;
	public boolean getfdTask(){return this.fdTask;}

	/**  * 文件块	*/
	@DataBaseAttribute(name="f_blockCount")
	public int blockCount=0;
	public int getblockCount(){return this.blockCount;}

	@DataBaseAttribute(name="f_blockSize")
	public int blockSize=0;//逻辑分块大小
	public int getblockSize(){return this.blockSize;}

	//块索引，基于1
	@DataBaseAttribute(name="f_blockIndex")
	public int blockIndex=0;
	public int getblockIndex(){return this.blockIndex;}


	//块偏移,基于整个文件
	@DataBaseAttribute(name="f_blockOffset")
	public long blockOffset=0;
	public long getblockOffset(){return this.blockOffset;}

	@DataBaseAttribute(name="f_encrypt")
	public boolean encrypt=false;
	public boolean getencrypt(){return this.encrypt;}

	//加密算法类型,aes,sm4
    @DataBaseAttribute(name="f_encryptAlgo")
    public String encryptAgo = "aes";
    public String getencryptAgo(){return this.encryptAgo;}

    //块加密标识
    public boolean blockEncrypt=false;
    //块加密大小
    public int blockSizeCry=0;
    //块压缩大小
    public int blockSizeCpr=0;
    //用于第三方存储的对象ID，如FastDFS,Minio等
    public String object_id="";

    //块压缩
    public boolean blockCompress = false;
    public String blockCprType = "gzip";

	public int fileCount=0;

	/**  * 是否是文件夹中的子文件*/
	@DataBaseAttribute(name="f_fdChild")
	public boolean fdChild=false;
	public boolean getfdChild(){return this.fdChild;}

	/**  * 用户ID。与第三方系统整合使用。	*/
	@DataBaseAttribute(name="f_uid")
	public String uid="";
	public String getuid(){return this.uid;}

	/**  * 文件在本地电脑中的名称	*/
	@DataBaseAttribute(name="f_nameLoc")
	public String nameLoc="";
	public String getnameLoc(){return this.nameLoc;}

	/**	 * 文件在服务器中的名称。	 */
	@DataBaseAttribute(name="f_nameSvr")
	public String nameSvr="";
	public String getnameSvr(){return this.nameSvr;}

	/**	 * 文件在本地电脑中的完整路径。示例：D:\Soft\QQ2012.exe	 */
	@DataBaseAttribute(name="f_pathLoc")
	public String pathLoc="";
	public String getpathLoc(){return this.pathLoc;}

	/**	 * 文件在服务器中的完整路径。示例：F:\\ftp\\uer\\md5.exe	 */
	@DataBaseAttribute(name="f_pathSvr")
	public String pathSvr="";
	public String getpathSvr(){return this.pathSvr;}

	/**	 * 文件相对路径(用于层级结构)。示例：md5.exe	 */
	@DataBaseAttribute(name="f_pathRel")
	public String pathRel="";
	public String getpathRel(){return this.pathRel;}

	/**  * 文件块目录 f:/webapps/files/年/月/日/guid/file-guid/	*/
	public String blockPath = "";

	/**	 * 文件MD5	 */
	@DataBaseAttribute(name="f_md5")
	public String md5="";
	public String getmd5(){return this.md5;}

	/**	 * 数字化的文件长度。以字节为单位，示例：120125	 */
	@DataBaseAttribute(name="f_lenLoc")
	public long lenLoc=0;
	public long getlenLoc(){return this.lenLoc;}

	/**
	 * 加密后的文件大小
	 */
	@DataBaseAttribute(name="f_lenLocSec")
	public long lenLocSec = 0;
	public long getlenLocSec(){return this.lenLocSec;}

	/**	 * 格式化的文件尺寸。示例：10.03MB	 */
	@DataBaseAttribute(name="f_sizeLoc")
	public String sizeLoc="";
	public String getsizeLoc(){return this.sizeLoc;}

	public String sizeSvr="0byte";
	public String getsizeSvr(){return this.sizeSvr;}

	/**	 * 已上传大小。以字节为单位	 */
	@DataBaseAttribute(name="f_lenSvr")
	public long lenSvr=0;
	public long getlenSvr(){return this.lenSvr;}

	/**	 * 已上传百分比。示例：10%	 */
	@DataBaseAttribute(name="f_perSvr")
	public String perSvr="0%";
	public String getperSvr(){return this.perSvr;}

	@DataBaseAttribute(name="f_complete")
	public boolean complete=false;
	public boolean getcomplete(){return this.complete;}

	@DataBaseAttribute(name="f_time")
	public Date time = new Date();
	public Date gettime(){return this.time;}

	@DataBaseAttribute(name="f_deleted")
	public boolean deleted=false;
	public boolean getdeleted(){return this.deleted;}

	/**	 * 是否已经扫描完毕，提供给大型文件夹使用，大型文件夹上传完毕后开始扫描。	 */
	@DataBaseAttribute(name="f_scan")
	public boolean scaned=false;
	public boolean getscaned(){return this.scaned;}
	
	/**	 * 存储类型：io,oss,obs,cos,aws。	 */
	@DataBaseAttribute(name="f_storage")
	public String storage="io";
	public String getstoarge(){return this.storage;}
	
	public StorageType storageType = StorageType.IO;
	
	/**	 * 对象存储key。	 */
	@DataBaseAttribute(name="f_object_key")
	public String objectKey="";
	public String getobjectKey(){return this.objectKey;}
	
	/**	 * 对象存储key.url。	 */
	@DataBaseAttribute(name="f_object_url")
	public String objectUrl="";
	public String getobjectUrl(){return this.objectUrl;}

	public String parentDir()
	{
		File f = new File(this.pathSvr);
		return f.getParent().replace('\\', '/');
	}

	/// <summary>
	/// 计算文件加密后的大小，16字节对齐
	/// </summary>
	public void calLenLocSec() {
		long a = this.lenLoc % 16;
		this.lenLocSec = this.lenLoc + (16 - (a > 0 ? a : 16));
		
		if (this.encryptAgo.equalsIgnoreCase("sm4"))
        {
            this.calLenLocSecSm4();
        }
	}

	/// <summary>
    /// sm4-cbc-pkcs5padding
    /// (块大小* 块对齐大小) + 最后一块对齐大小
    /// </summary>
    public void calLenLocSecSm4()
    {
        //每一块对齐大小
        this.blockSizeCry = UtilsTool.sm4AlignBlockSize(this.blockSize);

        //块总数-1 * 块对齐大小
        this.lenLocSec = (this.blockCount-1) * this.blockSizeCry;

        //最后一块对齐大小
        long lastSize = this.lenLoc % this.blockSize;
        lastSize = UtilsTool.sm4AlignBlockSize((int)lastSize);

        this.lenLocSec += lastSize;
    }
	
	public String schemaFile() {
		return this.parentDir().concat("/schema.txt");
	}

	public void saveScheme()
	{
		FolderSchema fs = new FolderSchema();
		this.calLenLocSec();//自动计算文件加密后的大小
		fs.addFile(this);
	}

	public String formatSize(long byteCount)
	{
		return PathTool.BytesToString(byteCount);
	}
}